package com.xw.service.tool.wechat;

import com.google.common.collect.Maps;
import com.xw.model.sdk.WeChatModel;
import com.xw.sdk.wechat.WXPayUtil;
import com.xw.util.AppUtil;
import com.xw.util.PropertiesUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
@Service
@Transactional(rollbackFor = Exception.class)
public class WeChatServiceImpl implements WeChatService {

    Map<String,Object> map =null;

    private final String appid = PropertiesUtil.getProperty("WEICHAT_APPID");
    private final String mchid = PropertiesUtil.getProperty("WEICHAT_MCHID");
    private final String tradetype = PropertiesUtil.getProperty("WEICHAT_TRADETYPE");
    private final String apikey = PropertiesUtil.getProperty("WEICHAT_APIKEY");
    /**
     * 统一下单
     * 商户系统先调用该接口在微信支付服务后台生成预支付交易单，
     * 返回正确的预支付交易会话标识后进行二次验签，
     * 将二次验签的数据返回给前段进行APP里面调起支付 。
     * URL地址：https://api.mch.weixin.qq.com/pay/unifiedorder
     * @param weChatModel
     * @param request
     * @return
     * @throws Exception
     */
    public Map toPay(WeChatModel weChatModel, HttpServletRequest request) throws Exception {
        map = Maps.newHashMap();
        weChatModel.setAppid(appid);
        weChatModel.setMch_id(mchid);
        weChatModel.setTrade_type(tradetype);
        //请求的实际ip地址
        weChatModel.setSpbill_create_ip(request.getRemoteAddr());
        weChatModel.setNonce_str(AppUtil.uuid().toUpperCase());

        Map<String, Object> stringObjectMap = AppUtil.objectToMap(weChatModel);
        Map<String, String> mapString = Maps.newHashMap();

        for (Map.Entry<String, Object> entry : stringObjectMap.entrySet()) {
            //将里面的空值过滤掉
            if (entry.getValue()!=null) {
                mapString.put(entry.getKey(), entry.getValue().toString());
            }
        }
        //生成带有sign的xml
        String xml = WXPayUtil.generateSignedXml(mapString, apikey);
//        System.out.println(">>>>>生成带有sign的xml"+xml);

        //调用接口方法
        String UTF8 = "UTF-8";
        String reqBody = xml;
        URL httpUrl = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");
        HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
        httpURLConnection.setRequestProperty("Host", "api.mch.weixin.qq.com");
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setConnectTimeout(10*1000);
        httpURLConnection.setReadTimeout(10*1000);
        httpURLConnection.connect();
        OutputStream outputStream = httpURLConnection.getOutputStream();
        outputStream.write(reqBody.getBytes(UTF8));

        //获取内容
        InputStream inputStream = httpURLConnection.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
        final StringBuffer stringBuffer = new StringBuffer();
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line);
        }
        //返回的结果
        String resp = stringBuffer.toString();
        Map<String, String> stringStringMap = WXPayUtil.xmlToMap(resp);

//        System.out.println("》》》》》》》》微信下单返回的参数"+JSONObject.toJSON(stringStringMap));
        //都返回success 就会有prepay_id
        if (stringStringMap.get("return_code").equals("SUCCESS") && stringStringMap.get("result_code").equals("SUCCESS")) {
            //预支付id
            String prepay_id = stringStringMap.get("prepay_id");
            long seconds = System.currentTimeMillis() / 1000;
            //二次验签
            Map<String, String> signParam = new HashMap<String, String>();
            signParam.put("appid", appid);//app_id
            signParam.put("partnerid", mchid);//微信商户账号
            signParam.put("prepayid", prepay_id);//预付订单id
            signParam.put("package", "Sign=WXPay");//默认sign=WXPay
            signParam.put("noncestr", AppUtil.uuid());//自定义不重复的长度不长于32位
            signParam.put("timestamp", String.valueOf(seconds));//北京时间时间戳 10位的
//            System.out.println("二次验签传参"+JSONObject.toJSON(signParam));
            //再次返回带sign签名的xml
            String signAgainXml = WXPayUtil.generateSignedXml(signParam, apikey);//再次生成签名
//            System.out.println("再次返回带sign签名的xml"+signAgainXml);
            Map<String, String> stringStringMap1 = WXPayUtil.xmlToMap(signAgainXml);
            map.put("body", stringStringMap1);
            map.put("code", 200);
        }else{
            map.put("msg","prepay_id获取有误");
            map.put("code", 101);
        }

        if (stringBuffer!=null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (inputStream!=null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (outputStream!=null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return map;
    }
}
